﻿using Microsoft.VisualBasic;
using MonitorPrism_Practice.Commons;
using SCADALight.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MonitorPrism_Practice.Services
{
    public interface IUndoRedoManager
    {
        bool CanUndo { get; }      
        bool CanRedo { get; }       
        string LastUndoDescription { get; } 
        string LastRedoDescription { get; }  

       
        void Execute(Action execute, Action undo, string description);  // 执行并记录操作
        void ExecuteWithRecord(IChangeRecord record);  // 执行并记录变更记录
        void Undo();  // 撤销操作
        void Redo();  // 重做操作
        void Clear();  // 清空历史记录
    }
    public class UndoRedoManager :BindableBase, IUndoRedoManager
    {
        private LogEventService _logEventService;
        private readonly BoundedStack<IChangeRecord> _undoStack = new BoundedStack<IChangeRecord>(10);
        private readonly BoundedStack<IChangeRecord> _redoStack = new BoundedStack<IChangeRecord>(10);
        public  int _maxHistoryCount => _undoStack._maxCapacity;
      

        public UndoRedoManager()
        {
            _logEventService = _logEventService = ContainerLocator.Current.Resolve<LogEventService>();
        }
        public bool CanUndo => _undoStack.Count > 0;
        public bool CanRedo => _redoStack.Count > 0;
        public string LastUndoDescription => CanUndo ? _undoStack.Peek().Description : "";
        public string LastRedoDescription => CanRedo ? _redoStack.Peek().Description : "";

        public void Clear()
        {
            _undoStack.Clear();
            _redoStack.Clear();
          
        }

        public void Execute(Action execute, Action undo, string description)
        {
            execute.Invoke();
            _undoStack.Push(new DeleteChangedRecord(execute, undo, description));
            _redoStack.Clear();
            if (_undoStack.Count > _maxHistoryCount)
                _undoStack.RemoveRange(0, _undoStack.Count - _maxHistoryCount);
        }
        public void Redo()
        {
            if (CanRedo)
            {
               
                var record = _redoStack.Pop();
                record.Redo();  // 执行重做
                _logEventService.AddItem(new LogEventModel() { Message = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} 发生了重做" });
                _undoStack.Push(record);  // 将记录移到撤销栈
            }
        }

        public void Undo()
        {
            if (CanUndo)
            {
                //int index = int.Parse(RedoCount);
                //RedoCount = (index + 1).ToString();
                var record = _undoStack.Pop();
                record.Undo();  // 执行撤销
                _logEventService.AddItem(new LogEventModel() { Message = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} 发生了撤销" });
                _redoStack.Push(record);  // 将记录移到重做栈
            }
        }

        public void ExecuteWithRecord(IChangeRecord record)
        {
          
        }
    }
    public interface IChangeRecord
    {
        void Undo();        // 撤销操作
        void Redo();        // 重做操作
        string Description { get; }  // 操作描述
    }
    //命令变更记录
    public class DeleteChangedRecord : IChangeRecord
    {
        public readonly Action _undoAction;
        public readonly Action _redoAction;
     
        public string Description { get; }

        public DeleteChangedRecord(Action undoAction, Action redoAction, string description)
        {
           
            _undoAction = undoAction;
            _redoAction = redoAction;
            Description = description;
        }
        public void Redo() => _undoAction();
        public void Undo() => _redoAction();
    }
    //集合添加记录
    public class CollectionAddRecord<T> : IChangeRecord
    {
        private readonly ObservableCollection<T> _collection;
        private readonly T _item;
        private readonly int _index;

        public CollectionAddRecord(ObservableCollection<T> collection, T item, int index)
        {
            _collection = collection;
            _item = item;
            _index = index;
            Description = $"添加 {item}";
        }

        public void Undo() => _collection.RemoveAt(_index);
        public void Redo() => _collection.Insert(_index, _item);
        public string Description { get; }
    }
    //集合删除记录
    public class CollectionRemoveRecord<T> : IChangeRecord
    {
        private readonly ObservableCollection<T> _collection;
        private readonly T _item;
        private readonly int _index;

        public CollectionRemoveRecord(ObservableCollection<T> collection, T item, int index)
        {
            _collection = collection;
            _item = item;
            _index = index;
            Description = $"删除 {item}";
        }
        public void Undo() => _collection.Insert(_index, _item);
        public void Redo() => _collection.RemoveAt(_index);
        public string Description { get; }
    }
    // 属性变更记录
    public class PropertyChangeRecord<T> : IChangeRecord
    {
        private readonly Action<T> _setValue;
        private readonly T _oldValue;
        private readonly T _newValue;

        public PropertyChangeRecord(Action<T> setValue, T oldValue, T newValue, string description)
        {
            _setValue = setValue;
            _oldValue = oldValue;
            _newValue = newValue;
            Description = description;
        }

        public void Undo() => _setValue(_oldValue);
        public void Redo() => _setValue(_newValue);
        public string Description { get; }
    }



}
